package llm

import (
	"context"
	"encoding/json"
	"fmt"
	"sync"

	"techoiceness.com/aiagent/llm-gateway/internal/entity"
	"techoiceness.com/aiagent/llm-gateway/internal/llm/interfaces"
	"techoiceness.com/aiagent/llm-gateway/internal/llm/providers"
	"techoiceness.com/aiagent/llm-gateway/internal/repository"
)

// ProviderManager 管理LLM提供者的选用和模型选择
type ProviderManager struct {
	mu           sync.RWMutex
	providerRepo repository.LLMProviderRepository

	availableProvider interfaces.LLMProvider // 当前可用的提供者(缓存，方便快速获取)
	availableModel    *entity.ModelInfo      // 当前可用的模型(缓存，方便快速获取)
}

// NewProviderManager 创建新的提供者管理器
func NewProviderManager(providerRepo repository.LLMProviderRepository) *ProviderManager {
	return &ProviderManager{
		providerRepo: providerRepo,
	}
}

// GetAvailableProvider 获取当前可用的提供者
func (pm *ProviderManager) GetAvailableProvider() interfaces.LLMProvider {
	pm.mu.RLock()
	defer pm.mu.RUnlock()
	return pm.availableProvider
}

// GetAvailableModel 获取当前可用的模型
func (pm *ProviderManager) GetAvailableModel() *entity.ModelInfo {
	pm.mu.RLock()
	defer pm.mu.RUnlock()
	return pm.availableModel
}

// IsProviderAvailable 检查当前是否有可用的provider
func (pm *ProviderManager) IsProviderAvailable() bool {
	pm.mu.RLock()
	defer pm.mu.RUnlock()
	return pm.availableProvider != nil
}

// LoadAvailable 从数据库加载当前可用的提供者和模型
func (pm *ProviderManager) LoadAvailable(ctx context.Context) error {
	// 从数据库获取当前使用的提供商配置
	dbAvailableProvider, err := pm.providerRepo.GetAvailableProvider(ctx)
	if err != nil {
		return fmt.Errorf("获取当前可用的提供商失败: %w", err)
	}

	// 解析模型列表
	var models []entity.ModelInfo
	if dbAvailableProvider.Models != nil {
		if err := json.Unmarshal(dbAvailableProvider.Models, &models); err != nil {
			// 如果解析失败，记录错误但继续，使用空的模型列表
			models = []entity.ModelInfo{}
		}
	}

	var availableModel *entity.ModelInfo
	if len(models) > 0 {
		availableModel = &models[0]

		for _, model := range models {
			if model.IsDefault {
				availableModel = &model
				break
			}
		}
	}

	// 根据数据库中的提供商配置创建提供者实例
	var availableProvider interfaces.LLMProvider
	switch dbAvailableProvider.ProviderType {
	case "deepseek":
		availableProvider = providers.NewDeepSeek(
			dbAvailableProvider.BaseURL,
			dbAvailableProvider.APIKey,
		)
	case "openai":
		// TODO: 实现OpenAI提供商
		return fmt.Errorf("OpenAI 提供商未实现")
	default:
		return fmt.Errorf("不支持的 LLM 提供商类型: %s", dbAvailableProvider.ProviderType)
	}

	pm.mu.Lock()
	defer pm.mu.Unlock()

	pm.availableProvider = availableProvider
	pm.availableModel = availableModel

	return nil
}
